Chapter 0: FP Basic
함수형 프로그래밍을 접하기 전에 알아야할 기본 지식들
Imperative

Functional

1. Pure Function (순수함수)
순수함수란
- 같은 input ⇒ 같은 output
- 언제 어디서 실행하든지 항상 같은 결과
- 부수효과(side effect)가 없음
function PureAdd(a, b) {
return a + b;
}
let b = 1;
function NonPureAdd(a) {
return a + b;
}
function SideEffectAdd(a, b) {
console.log('hi!');
return a + b;
}
2. First Class Function (일급함수)
함수를 값으로 다룰 수 있다
// Can assign to variable
const add = (a, b) => a + b;
// Can pass function as parameter
[1, 2, 3].reduce(add);
// Function can return another function
const subtract = (a) => (b) => a - b;
3. Iterator Protocol
객체가 iterable 하기 위해서는 iterable protocol 을 따라야 합니다.
// Iterate Map
for (const el of new Map([
['a', 1],
['b', 2],
])) {
console.log(el);
}
// Iterate Set
for (const el of new Set([1, 2, 3])) {
console.log(el);
}
// Iterate Array
for (const el of ['lodash', 'ramda', 'fxts']) {
console.log(el);
}
// Iterate plain object
const obj = { a: 1, b: 2 };
for (const el of obj) {
console.log(el); // Uncaught TypeError: obj is not iterable
}
기본 객체를 iterable 하도록 만들어 봅시다.
// Declare non iterable object
const obj = {
a: 1,
b: 2,
c: 3,
};
// Set [Symbol.iterator] property
obj[Symbol.iterator] = function () {
let i = 0;
const values = Object.values(this);
return {
next() {
return i == values.length ? { done: true } : { value: values[i++], done: false };
},
[Symbol.iterator]() {
return this;
}, // well-formed iterator
};
};
// Now we can iterate `obj` with `for of` statement.
for (const el of obj) {
console.log(el); // 1 2 3
}
4. Generator
제너레이터를 사용하면 iterable 한 객체를 쉽게 구현할 수 있습니다.
function* gen() {
yield 1;
yield 2;
yield 3;
}
const iter = gen();
iter.next(); // { value: 1, done: false }
iter.next(); // { value: 2, done: false }
iter.next(); // { value: 3, done: false }
iter.next(); // { value: undefined, done: true }
제너레이터를 응용하면 무한으로 iterable 한 iterator 를 만들 수 있습니다.
function *infinite() {
let i = -1;
while (true) {
yield ++i;
}
}
const iter = infinite();
iter.next(); // { value: 1, done: false }
iter.next(); // { value: 2, done: false }
iter.next(); // { value: 3, done: false }
...